package rbm.modelado.datos.elementos;

import modelado.datos.elementos.VerticeImpl;
import rbm.modelado.datos.elementos.interfaces.BlockShape;
import rbm.modelado.datos.elementos.interfaces.Path;
import rbm.modelado.global.interfaces.PuzzleConstants;


public class BlockPosNode extends VerticeImpl implements PuzzleConstants
{

   private Integer xPos, yPos;

   private BlockShape shape;
   private Integer minMoves;
   private Integer numBranches;
   private Integer numDirectionChanges;

   private BlockPosNode nextNode = null;

   private Integer lastMoveDir;
   private BlockPosNode lastVisited = null;

   private Boolean countedInLoop = false;



   public BlockPosNode( Integer x, Integer y, BlockShape s, Integer m, BlockPosNode last, Integer dir, Integer br, Integer ch )
   {
      xPos = x;
      yPos = y;
      shape = s;
      minMoves = m;
      lastVisited = last;
      lastMoveDir = dir;
      numBranches = br;
      numDirectionChanges = ch;
   }

   public Integer getXPos()
   {
      return xPos;
   }

   public Integer getYPos()
   {
      return yPos;
   }

   public BlockShape getShape()
   {
      return shape;
   }

   public Integer getMinMoves()
   {
      return minMoves;
   }

   public Integer getNumBranches()
   {
      return numBranches;
   }

   public Integer getNumDirectionChanges()
   {
      return numDirectionChanges;
   }

   public void updateNode( Integer m, BlockPosNode last, Integer dir, Integer br )
   {
      minMoves = m;
      lastVisited = last;
      lastMoveDir = dir;
      numBranches = br;
   }

   public boolean addNode( BlockPosNode node )
   {
      if( nextNode == null )
      {
         nextNode = node;
         return true;
      }
      else
         return false;
   }

   public Integer getLastMove()
   {
      return lastMoveDir;
   }

   public BlockPosNode getLastVisited()
   {
      return lastVisited;
   }

   public BlockPosNode getNextNode()
   {
      return nextNode;
   }


   public boolean isCountedInLoop()
   {
      return countedInLoop;
   }


   public void setCountedInLoop()
   {
      countedInLoop = true;
   }


   public Path tracePath()
   {
	   Path path = new PathImpl(minMoves);
      return tracePath( path );
   }


   public Path tracePath( Path path1 )
   {
	   PathImpl path = (PathImpl) path1;
      if( minMoves <= 0 )
         return path;

      path.set(minMoves - 1, lastMoveDir);

      return lastVisited.tracePath( path );
   }


   public void printSolution()
   {
      if( lastVisited != null )
      {
         lastVisited.printSolution();
         System.out.print( ", " );
      }

      String s;

      switch( lastMoveDir )
      {
         case( UP ) : s = "up"; break;
         case( DOWN ) : s = "down"; break;
         case( LEFT ) : s = "left"; break;
         case( RIGHT ) : s = "right"; break;
         case( START ) : s = "START"; break;
         default : s = "ERROR";
      }

      System.out.print( s );
   }


}